import React from 'react'
// import * as React from 'react';
import cloneDeep from 'clone-deep'
// import ReactDOM from 'react-dom';
import * as ReactDOM from 'react-dom'
import { Select } from 'antd'
import config from '@/config'
import req from './request'

export const request = req

const { prefix, apiPrefix, baseURL } = config

/**
 * localStorage: set get remove clear
 */
export const cache = {
  set(key: string, content: any) {
    if (!key) return
    if (typeof content !== 'string') {
      content = JSON.stringify(content)
    }
    window.localStorage.setItem(`${prefix}_${key}`, content)
  },
  get(key: string) {
    if (!key) return
    return window.localStorage.getItem(`${prefix}_${key}`) || ''
  },
  remove(key: string) {
    key
      ? window.localStorage.removeItem(`${prefix}_${key}`)
      : window.localStorage.clear()
  },
  clear() {
    window.localStorage.clear()
  },
}
/**
 * cookie: set get remove clear
 */
export const cookie = {
  set(key: string, content: any, exdays: number = 1) {
    const now = new Date()
    now.setTime(now.getTime() + exdays * 24 * 60 * 60 * 1000)
    const expires = 'expires=' + now.toUTCString()
    // document.cookie = key + "=" + JSON.stringify(content) + "; " + expires;
    document.cookie = `${key}=${JSON.stringify(content)};${expires}`
  },
  get(key: string) {
    const name = key + '='
    const ca = document.cookie.split(';')
    for (let i = 0; i < ca.length; i++) {
      let c = ca[i]
      while (c.charAt(0) === ' ') c = c.substring(1)
      if (c.indexOf(name) !== -1) return c.substring(name.length, c.length)
    }
    return ''
  },
  remove(name: string) {
    this.set(name, '', -1)
  },
  clear() {
    const keys = document.cookie.match(/[^ =;]+(?==)/g)
    if (keys) {
      for (let i = keys.length; i--; ) {
        this.remove(keys[i])
        document.cookie = keys[i] + '=0;expires=' + new Date(0).toUTCString()
      }
    }
  },
}

/**
 * 删除所有cookie
 */
export function deleteAllCookies() {
  var cookies = document.cookie.split(';')

  for (var i = 0; i < cookies.length; i++) {
    var cookie = cookies[i]
    var eqPos = cookie.indexOf('=')
    var name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie
    document.cookie = name + '=;expires=Thu, 01 Jan 1970 00:00:00 GMT'
  }
}

/**
 * 单列数组to树状结构
 * @param   {array}     array
 * @param   {String}    id 当前唯一标识
 * @param   {String}    pid 父节点标识
 * @param   {String}    children 生成后子节点字段
 * @return  {Array}
 */
export function arrayToTree(
  array = [],
  id = 'id',
  pid = 'pid',
  children = 'children',
) {
  let data = cloneDeep(array)
  let result = [] as []
  let hash = {}
  data.forEach((item, index) => {
    hash[data[index][id]] = data[index]
  })

  data.forEach((item) => {
    let hashVP = hash[item[pid]] as any
    if (hashVP) {
      // eslint-disable-next-line no-unused-expressions
      !hashVP[children] && (hashVP[children] = [])
      hashVP[children].push(item)
    } else {
      result.push(item)
    }
  })
  return result
}

/**
 * 树状结构to单列数组
 * @param   {array}     array
 * @param   {String}    children 生成后子节点字段
 * @return  {Array}
 */
export function treeToArray(array: any = [], children = 'children') {
  const data = cloneDeep(array)
  const result: any = []

  const forArr = (list: any = []) => {
    list.forEach((_: any) => {
      if (_[children]) {
        forArr(_[children])
      }
      result.push(_)
    })
  }
  forArr(data)

  return result
}

export function delay(millis: number) {
  return new Promise(function (resolve, reject) {
    return setTimeout(() => resolve(), millis)
  })
}

/**
 * 下载
 * @param {*Object} options 配置项
 * @argument {String} id form下载的包裹元素id
 * @argument {String} method 下载请求方式
 * @argument {*String} url 下载action
 * @argument {*Object} data 下载参数
 * @argument {Object} name 下载参数name
 */
export function download(options: any) {
  const {
    id = 'download',
    method = 'post',
    url,
    name = 'params',
    data,
  } = options

  const isFullUrl = /^https?:\/\/.+/.test(url) // 全链接接口
  const downloadURL = isFullUrl ? url : baseURL + apiPrefix + url
  // const downloadURL = url.indexOf('//') < 0 ? baseURL + apiPrefix + url : url

  const params = cloneDeep(data) as any

  const downloadDiv: any =
    document.getElementById(id) || document.createElement('div')
  downloadDiv.id = id
  document.body.appendChild(downloadDiv)

  ReactDOM.render(
    <form
      style={{ display: 'none' }}
      action={`${downloadURL}?${name}=${encodeURI(JSON.stringify(params))}`}
      method={method}
      encType="multipart/form-data"
    ></form>,
    downloadDiv,
  )
  downloadDiv.querySelector('form').submit()
  // ReactDOM.findDOMNode(downloadDiv).querySelector('form').submit();
  ReactDOM.unmountComponentAtNode(downloadDiv)
}

/**
 * 解析URL(从哈希、检索值中)
 * @argument {String} hash
 * @argument {String} search
 * @returns {Object} URL中所携带的参数
 */
export function parseURL(
  hash = window.location.hash,
  search = window.location.search,
) {
  let params = {} as any
  hash = hash.startsWith('#') ? hash.replace('#', '') : hash
  let suffixStr = search.includes('?') ? search : hash

  const searchStr = suffixStr.split('?')[1] || ''
  const paramsList = searchStr.split('&')
  paramsList.forEach((_) => {
    params[_.split('=')[0]] = _.split('=')[1]
  })
  return params
}

/**
 * 获取url中的参数
 */
export const getQueryString = (name: string) => {
  let reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i')
  let r = window.location.search.substr(1).match(reg)
  if (r != null) return unescape(r[2])
  return null
}

/**
 * Select组件Options的映射
 * @param list
 * @param id 表示value的字段
 * @param name 表示label的字段
 * @returns {ReactNode} Options
 */
export const optionsMap = (list: any[] = [], id = 'code', name = 'name') =>
  list.map((_) => (
    <Select.Option key={_[id]} value={_[id]}>
      {_[name]}
    </Select.Option>
  ))
/**
 * Select组件labelInValue模式时值的处理(单选模式)
 * @param info 值信息
 * @param id 信息中value的字段
 * @param name 信息中label的字段
 * @returns {Object | undefined} 示例格式: {value: string, label: ReactNode}
 */
export const toLabelInValue = (info: any = {}, id = 'value', name = 'label') =>
  info[id]
    ? {
        value: info[id],
        label: info[name],
      }
    : undefined

/**
 * Select组件labelInValue模式时值的处理(多选模式)
 * @param info 值信息
 * @param id 信息中value的字段
 * @param name 信息中label的字段
 * @returns {Object} 示例格式: [{value: string, label: ReactNode}, ...]
 */
export const toLabelsInValues = (
  info: any = {},
  id = 'value',
  name = 'label',
  separator = ';',
) => {
  const ids = info[id] ? String(info[id]).split(separator) : []
  const names = info[name] ? String(info[name]).split(separator) : []
  return ids.map((_: any, i: number) => ({
    value: _,
    label: names[i],
  }))
}
